﻿using System;
using System.ComponentModel;
using System.Threading;
using System.Windows.Forms;
using pub.GUI;
using pub.NET20Fix;

namespace pub.NET20Fix
{
    public class Dispatcher : ISynchronizeInvoke
    {
        private ISynchronizeInvoke _invoke;
        public static Dispatcher Current { get; set; }


        public Dispatcher()
        {
        }

        public Dispatcher(ISynchronizeInvoke invoke)
        {
            _invoke = invoke;
        }

        public virtual IAsyncResult BeginInvoke(Delegate method, object[] args)
        {
            return _invoke.BeginInvoke(method, args);
        }

        public virtual object EndInvoke(IAsyncResult result)
        {
            return _invoke.EndInvoke(result);
        }

        public virtual object Invoke(Delegate method, object[] args)
        {
            return _invoke.Invoke(method, args);
        }

        public object Invoke(Action action)
        {
            return Invoke(action, new object[0]);
        }

        public virtual bool InvokeRequired
        {
            get { return _invoke.InvokeRequired; }
        }
    }

    public class SynchronizationDispatcher : Dispatcher
    {
        private SynchronizationContext _sc;

        public SynchronizationDispatcher(SynchronizationContext sc)
        {
            _sc = sc;
        }

        public override IAsyncResult BeginInvoke(Delegate method, object[] args)
        {
            throw new NotImplementedException();
            return base.BeginInvoke(method, args);
        }

        public override object EndInvoke(IAsyncResult result)
        {
            throw new NotImplementedException();
            return base.EndInvoke(result);
        }

        public override object Invoke(Delegate method, object[] args)
        {
            object result = null;
            _sc.Send(state => { result = method.DynamicInvoke(args); }, null);
            return result;
        }

        public override bool InvokeRequired
        {
            get { return SynchronizationContext.Current != _sc; }
        }
    }

    public class LastFormDispatcher : Dispatcher
    {
        private Form Form
        {
            get { return FormUtils.GetLastForm(); }
        }

        public override IAsyncResult BeginInvoke(Delegate method, object[] args)
        {
            return Form.BeginInvoke(method, args);
        }

        public override object EndInvoke(IAsyncResult result)
        {
            return Form.EndInvoke(result);
        }

        public override object Invoke(Delegate method, object[] args)
        {
            return Form.Invoke(method, args);
        }

        public override bool InvokeRequired
        {
            get { return Form.InvokeRequired; }
        }
    }
}